package com.unbiz.common.bean;

import java.io.InputStream;
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
import java.util.HashMap;  
import java.util.Map;

import com.unbiz.common.StringUtil;
import com.unbiz.common.cache.MethodCache;
  
/**
 * 使用Hash Map来实现代理接口的entity对象
 * 如果输入接口实现了toMap返回MapEntityProxy.map
 * @author Hunteron-cp
 *
 */
public class MapEntityProxy implements InvocationHandler {  
	static MethodCache methodCache = MethodCache.getInstance();
	 
    private Map<String, Object> map = null;   
    
    //支持多接口的实现
    public static Object create(Class ... interfaces) {  
    	InvocationHandler handler =  new MapEntityProxy(interfaces);
        return Proxy.newProxyInstance(MapEntityProxy.class.getClassLoader(),  
                interfaces, handler);  
    }  
    
    public static <T> T create(Class<T> theInterface) {  
    	InvocationHandler handler =  new MapEntityProxy(theInterface);
    	Class<T> proxyClass = (Class<T>)Proxy.getProxyClass(theInterface.getClassLoader(), theInterface);
    	
    	T f = null;
		try {
			f = (T) proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
				| NoSuchMethodException | SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 
        return f;  
    }  
    
   
  
    private MapEntityProxy(Class<?>[] interfc) {  
        this.map = new HashMap<String, Object>();  
    }  
    
    private MapEntityProxy(Class<?> interfc) {  
        this.map = new HashMap<String, Object>();  
    }  
    
    @Override  
    public Object invoke(Object proxy, Method method, Object[] args)  
            throws Throwable {  
        Object result = null;  
        String methodName = method.getName();  
        boolean zeroArgs = args == null || args.length == 0;        
        if (methodName.equals("toString") && zeroArgs) {
            return map.toString();  
        } 
        else if (methodName.equals("hashCode") && zeroArgs){
            return map.hashCode();
        }
        else if (methodName.equals("equals") && !zeroArgs){
            return map.equals(args[0]);
        }
        else if (methodName.equals("toMap") && zeroArgs){
            return map;
        }
        else if (methodName.startsWith("get") && zeroArgs) {  
            String name = StringUtil.decapitalize(methodName.substring(3));  
            return map.get(name);  
        }
        else if (methodName.startsWith("set") && !zeroArgs) {  
            String name = StringUtil.decapitalize(methodName.substring(3));  
            map.put(name, args[0]);  
            return null;  
        }else if (methodName.startsWith("is") && zeroArgs) {  
            String name = StringUtil.decapitalize(methodName.substring(2));  
            return (map.get(name));  
        }   
        else{
        	throw new UnsupportedOperationException(methodName);
        }
        //return result;  
    }  
  
}  